/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.xuexiang.xuidemo.view;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.TextField;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Point;
import ohos.app.Context;

import com.xuexiang.xuidemo.ResourceTable;
import com.xuexiang.xuidemo.util.ElementHelper;

import java.util.ArrayList;

/**
 * 扩展处理输入状态和焦点状态监听的TextField
 *
 * @since 2021-03-27
 */
public class CustomEditText extends TextField {
    private final ArrayList<OnTextCursorChangedListener> textCursorChangedListeners = new ArrayList<>();
    private final ArrayList<OnFocusChangedListener> focusChangedListeners = new ArrayList<>();
    private final Paint paint = new Paint();

    {
        paint.setStyle(Paint.Style.STROKE_STYLE);
        final int defaultWidth = 4;
        paint.setStrokeWidth(defaultWidth);
    }

    private Point start;
    private Point end;
    private boolean isInputError = false;

    /**
     * 默认构造
     *
     * @param context 上下文
     */
    public CustomEditText(Context context) {
        super(context);
        init();
    }

    /**
     * 默认构造
     *
     * @param context 上下文
     * @param attrSet 属性集
     */
    public CustomEditText(Context context, AttrSet attrSet) {
        super(context, attrSet);
        init();
    }

    /**
     * 默认构造
     *
     * @param context 上下文
     * @param attrSet 属性集
     * @param styleName 样式名称
     */
    public CustomEditText(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init();
    }

    private void init() {
        setEstimateSizeListener(new EstimateSizeListener() {
            @Override
            public boolean onEstimateSize(int i, int i1) {
                int width = EstimateSpec.getSize(i);
                int height = EstimateSpec.getSize(i1);
                start = new Point(0, height - paint.getStrokeWidth());
                end = new Point(width, height - paint.getStrokeWidth());
                return false;
            }
        });
        initDrawTask();
        initStateListener();
    }

    private void initStateListener() {
        setCursorChangedListener(new CursorChangedListener() {
            @Override
            public void onCursorChange(TextField textField, int i, int i1) {
                if (textCursorChangedListeners.size() > 0) {
                    for (OnTextCursorChangedListener listener : textCursorChangedListeners) {
                        listener.onCursorChange(textField, i, i1);
                    }
                }
            }
        });
        setFocusChangedListener(new FocusChangedListener() {
            @Override
            public void onFocusChange(Component component, boolean isFocused) {
                if (focusChangedListeners.size() > 0) {
                    for (OnFocusChangedListener listener : focusChangedListeners) {
                        listener.onFocusChange(component, isFocused);
                    }
                }
                invalidate();
            }
        });
    }

    private void initDrawTask() {
        addDrawTask(new DrawTask() {
            @Override
            public void onDraw(Component component, Canvas canvas) {
                final int errorWidth = 6;
                final int normalWidth = 4;
                if (isFocused()) {
                    paint.setStrokeWidth(errorWidth);
                    if (isInputError) {
                        paint.setColor(ElementHelper.getColor(getContext(), ResourceTable.Color_login_red_light));
                    } else {
                        paint.setColor(ElementHelper.getColor(getContext(), ResourceTable.Color_login_blue_light));
                    }
                } else {
                    if (isInputError) {
                        paint.setStrokeWidth(errorWidth);
                        paint.setColor(ElementHelper.getColor(getContext(), ResourceTable.Color_login_red_light));
                    } else {
                        paint.setStrokeWidth(normalWidth);
                        paint.setColor(ElementHelper.getColor(getContext(), ResourceTable.Color_login_gray_light));
                    }
                }
                canvas.drawLine(start, end, paint);
            }
        });
    }

    /**
     * 是否输入错误
     *
     * @param isError 是否输入错误
     */
    public void setInputError(boolean isError) {
        this.isInputError = isError;
        invalidate();
    }

    public boolean isInputError() {
        return this.isInputError;
    }

    /**
     * 设置输入文字监听
     *
     * @param listener 监听器
     */
    public void addTextCursorChangedListener(OnTextCursorChangedListener listener) {
        if (!textCursorChangedListeners.contains(listener)) {
            this.textCursorChangedListeners.add(listener);
        }
    }

    /**
     * 移除输入文字监听
     *
     * @param listener 监听器
     */
    public void removeTextCursorChangedListener(OnTextCursorChangedListener listener) {
        this.textCursorChangedListeners.remove(listener);
    }

    /**
     * 设置焦点状态监听
     *
     * @param listener 监听器
     */
    public void addOnFocusChangedListener(OnFocusChangedListener listener) {
        if (!focusChangedListeners.contains(listener)) {
            this.focusChangedListeners.add(listener);
        }
    }

    /**
     * 移除焦点状态监听
     *
     * @param listener 监听器
     */
    public void removeOnFocusChangedListener(OnFocusChangedListener listener) {
        this.focusChangedListeners.remove(listener);
    }

    /**
     * 输入文字变化监听器
     *
     * @since 2021-03-27
     */
    public interface OnTextCursorChangedListener {
        /**
         * 输入文字变化回调
         *
         * @param textField 输入框
         * @param posStart 输入前光标索引
         * @param posAfter 输入后光标索引
         */
        void onCursorChange(TextField textField, int posStart, int posAfter);
    }

    /**
     * 焦点变化监听器
     *
     * @since 2021-03-27
     */
    public interface OnFocusChangedListener {
        /**
         * 焦点变化回调
         *
         * @param component 视图组件
         * @param isFocused 当前是否获取焦点
         */
        void onFocusChange(Component component, boolean isFocused);
    }
}
